package com.extremelylargepackage.level;

import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;

import org.w3c.dom.Element;

import com.extremelylargepackage.GameState;
import com.extremelylargepackage.entity.Enemy;
import com.extremelylargepackage.entity.Entity;

/*
 * Command events are used as a way to change game data 
 */
public class CommandEvent implements LevelEvent
{
	//Bit masks
	public static final int SET_BACKGROUND_SCROLL_SPEED = 0x00000001;
	public static final int WAIT = 0x00000002;
	public static final int SET_PLAYER_DESTINATION = 0x00000004;
	public static final int PLAYER_WEAPON_ENABLED = 0x00000008;
	public static final int PAUSE_ACTION = 0x00000010;
	
	private int _commands;
	private transient GameState _state;
	private boolean _executed;
	private long _timeElapsed;

	private int _backgroundScrollSpeed;
	private long _waitTime;
	private transient Point _playerDestination;
	private boolean _playerWeaponEnable;
	private boolean _pauseAction;
	
	@Override
	public void updateState(long time) 
	{
		_executed = true;
		if((_commands & SET_BACKGROUND_SCROLL_SPEED) == SET_BACKGROUND_SCROLL_SPEED)
			_state.setBackgroundScrollSpeed(_backgroundScrollSpeed);
		//For the wait command we set _executed to false to indicate
		//we are not done waiting.
		if((_commands & WAIT) == WAIT && _timeElapsed <= _waitTime)
			_executed = false;
		if((_commands & SET_PLAYER_DESTINATION) == SET_PLAYER_DESTINATION)
			_state.setPlayerDestination(_playerDestination.x, _playerDestination.y);
		if((_commands & PLAYER_WEAPON_ENABLED) == PLAYER_WEAPON_ENABLED)
			_state.setPlayerWeaponEnabled(_playerWeaponEnable);
		if((_commands & PAUSE_ACTION) == PAUSE_ACTION)
			_state.setActionPaused(_pauseAction);
		_timeElapsed += time;
	}

	@Override
	public boolean finished() 
	{
		return _executed;
	}

	@Override
	public Map<Integer, Enemy> getEnemies() 
	{
		return Collections.emptyMap();
	}

	@Override
	public Collection<Entity> getScenery() 
	{
		return Collections.emptyList();
	}

	public void setGameState(GameState state)
	{
		_state = state;
	}
	
	public static CommandEvent parseCommandEvent(Element element) throws MalformedLevelException
	{
		CommandEvent event = new CommandEvent();
		String scrollSpeed = element.getAttribute("setScrollSpeed");
		if(scrollSpeed != null && !scrollSpeed.equals(""))
		{
			event._commands |= SET_BACKGROUND_SCROLL_SPEED;
			event._backgroundScrollSpeed = Integer.parseInt(scrollSpeed);
		}
		String waitTime = element.getAttribute("wait");
		if(waitTime != null && !waitTime.equals(""))
		{
			event._commands |= WAIT;
			event._waitTime = LevelParser.parseTimeValue(waitTime);
		}
		String point = element.getAttribute("setPlayerDestination");
		if(point != null && !point.equals(""))
		{
			event._commands |= SET_PLAYER_DESTINATION;
			Point dest = LevelParser.parsePoint(point);
			event._playerDestination = dest;
		}
		String playerWeaponEnabled = element.getAttribute("playerWeaponEnabled");
		if(playerWeaponEnabled != null && !playerWeaponEnabled.equals(""))
		{
			event._commands |= PLAYER_WEAPON_ENABLED;
			event._playerWeaponEnable = Boolean.parseBoolean(playerWeaponEnabled);
		}
		String pauseAction = element.getAttribute("pauseAction");
		if(pauseAction != null && !pauseAction.equals(""))
		{
			event._commands |= PAUSE_ACTION;
			event._pauseAction = Boolean.parseBoolean(pauseAction);
		}
		return event;
	}
}
